home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
590
/
590.xpi
/
chrome
/
ipv6ident.jar
/
content
/
ipv6ident.js
< prev
next >
Wrap
Text File
|
2009-04-11
|
21KB
|
702 lines
/*
ShowIP Firefox Extension
Copyright (C) 2007 Jan Dittmer <jdi@l4x.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
const IPV6_NOTIFY_STATE_DOCUMENT =
Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT;
const IPV6_NOTIFY_LOCATION =
Components.interfaces.nsIWebProgress.NOTIFY_LOCATION;
const IPV6_STATE_IS_DOCUMENT =
Components.interfaces.nsIWebProgressListener.STATE_IS_DOCUMENT;
const IPV6_STATE_START =
Components.interfaces.nsIWebProgressListener.STATE_START;
//const IPV6_NOTIFY_ALL =
// Components.interfaces.nsIWebProgressListener.NOTIFY_ALL;
const SHOWIP_RESOLVE_BYPASS_CACHE = 1;
const SHOWIP_RESOLVE_CANONICAL_NAME = 2;
window.addEventListener("load", function() { showipExt.init(); }, false);
//window.addEventListener("unload", function() { showipExt.destroy(); }, false);
var showipExtRunOnce = 0;
var showipExt = {
init: function() {
if(showipExtRunOnce == 1) { return; }
showipExtRunOnce = 1;
this.localip = null;
this.updating = false;
this.purgecache();
this.strings = document.getElementById("showip_strings");
this.currenthost = null;
this.displayhost = 'not null ;-)';
this.currentstatus = 'none';
this.currentip = null;
this.panelText = 'init';
// shamelessly taken from flagfox extension
this.Listener = {
// this gets nsIWebProgress and nsIRequest
onLocationChange:function(aProgress,aRequest,aLocation) {
var host = 'none';
var scheme = 'none';
// try to prevent strange NS_ERRORS from StringBundle...
try {
host = aLocation.host;
scheme = aLocation.scheme;
} catch(e) {
host = 'none';
scheme = 'none';
}
if (!host || (host == '')) {
host = 'none';
}
if ( (scheme == 'chrome') || (scheme == 'file') ) {
host = 'none';
}
this.parent.updatestatus(host);
},
onStateChange:function(aProgress,aRequest,aFlag,aStatus) {},
onProgressChange:function(a,b,c,d,e,f){},
onStatusChange:function(a,b,c,d){},
onSecurityChange:function(a,b,c){},
onLinkIconAvailable:function(a){}
}; // this.Listener
this.Listener.parent = this;
this.PrefObserver = {
register: function() {
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);
this._branch = prefService.getBranch(""); // listen to all changes to also catch socks_remote_dns changes
var pbi = this._branch.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
pbi.addObserver("", this, false);
},
unregister: function()
{
if(!this._branch) return;
var pbi = this._branch.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
pbi.removeObserver("", this);
},
observe: function(aSubject, aTopic, aData)
{
if(aTopic != "nsPref:changed") return;
if (!aData) return;
if(aData.indexOf('ipv6ident')!=-1) {
this.parent.prefs.Init();
}
if( (aData.indexOf('network.proxy')!=-1)||
(aData.indexOf('ipv6ident')!=-1)) {
this.parent.updatesockspref(1);
}
}
}; // this.prefObserver
this.PrefObserver.parent = this;
// load preferences
this.prefs = showipExtPrefs;
this.prefs.Init();
// defer the notifier a bit, so that it shows after the main window
// to not confuse the users
window.setTimeout( function() { showipExt.prefs.checkblacklist(); }, 2000);
this.ipv6enabled = !this.prefs.prefs.getBoolPref("network.dns.disableIPv6");
// needed for ff < 3
var appcontent = document.getElementById("appcontent");
appcontent.addEventListener("load", this.onPageLoad, true);
if (gBrowser && gBrowser.tabContainer) {
// ff2+
gBrowser.tabContainer.addEventListener("TabSelect",
function(event) {
var browser = gBrowser.selectedTab.linkedBrowser;
//alert("Tab select " + browser.currentURI.host);
try {
showipExt.updatestatus(browser.currentURI.host);
} catch(e) {
showipExt.updatestatus('none');
}
} ,false);
}
window.getBrowser().addProgressListener(this.Listener,
IPV6_NOTIFY_LOCATION | IPV6_NOTIFY_STATE_DOCUMENT);
this.PrefObserver.register();
this.updatesockspref(0);
},
updatesockspref: function(updatestatus) {
var srdprefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
try {
var sh = srdprefs.getCharPref("network.proxy.socks"); // string
var sp = srdprefs.getIntPref("network.proxy.socks_port");
var sv = srdprefs.getIntPref("network.proxy.socks_version"); // dns socks only supported for version 5
var srd = srdprefs.getBoolPref("network.proxy.socks_remote_dns");
var pt = srdprefs.getIntPref("network.proxy.type"); // == 1 for proxy
this.socks_remote_dns = sh && sp && sv && srd &&
(sh != '') && (sp > 0) && (sv > 4) && (pt == 1) && (this.prefs.forcesocks == false);
//alert(this.prefs.forcesocks + ',' + this.socks_remote_dns + ',' + sh + ',' + sp + ',' + sv + ',' + pt + ',' + (this.prefs.forcesocks == false));
} catch(e) {
this.socks_remote_dns = false;
}
this.purgecache();
this.displayhost = '';
this.localip = null;
if (updatestatus)
this.updatestatus(this.currenthost);
},
useproxy: function (url) {
// detect if the given url would use a proxy for dns resolution
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var pps = Components.classes["@mozilla.org/network/protocol-proxy-service;1"]
.getService(Components.interfaces.nsIProtocolProxyService);
try {
var uri = ios.newURI(url, null, null);
var pi = pps.resolve(uri, 0);
// TRANSP... is only set in case of a SOCKS proxy (see nsProtocolProxyService.cpp#1329)
return (pi != null);// && (pi.flags & pi.TRANSPARENT_PROXY_RESOLVES_HOST);
} catch (e) {
dump(e.description);
return false;
}
},
purgecache: function () {
this.dnscache = new Array();
this.dnscache['none'] = new Array();
this.dnscache['exception'] = new Array();
this.dnscache['string_none'] = new Array();
this.dnscache['string_exception'] = new Array();
},
destroy: function() {
this.PrefObserver.unregister();
window.getBrowser().removeProgressListener(this.Listener);
},
// 'load' event handler, necessary??
onPageLoad: function(e) {
var doc = e.originalTarget;
if (doc && doc.location &&
(
(doc.location.protocol == 'http:') ||
(doc.location.protocol == 'ftp:') ||
0
)
) {
showipExt.updatestatus(doc.location.host);
} else {
showipExt.updatestatus("none");
}
},
getdns: function() {
var cls = Components.classes['@mozilla.org/network/dns-service;1'];
var iface = Components.interfaces.nsIDNSService;
var dns = cls.getService(iface);
return dns;
},
// setup ipv6_localip with all local ips
getLocalIp: function() {
if (this.socks_remote_dns)
return "Disabled due to SOCKS proxy";
if (this.localip)
return this.localip;
var a = new Array();
// doc.location is the Location object
try {
var dns = this.getdns();
var nsrecord = dns.resolve(dns.myHostName, true);
while (nsrecord && nsrecord.hasMore()) {
a[a.length] = nsrecord.getNextAddrAsString();
}
this.localip = a.join(" | ");
} catch (e) {
this.localip = dns.myHostName + " not resolvable";
}
return this.localip;
},
// return the ip of host
resolveIp: function(host) {
if (this.socks_remote_dns)
return new Array();
var asyncLookup = this.prefs.asyncresolve;
var dns = this.getdns();
try {
if (asyncLookup) {
var dnslistener = {
onLookupComplete: function(aRequest, aRecord, aStatus) {
var ip = new Array();
while(aRecord && aRecord.hasMore()) {
ip.push(aRecord.getNextAddrAsString());
}
this.parent.updatestatus(this.host, ip);
}
};
var th;
if (Components.classes["@mozilla.org/event-queue-service;1"]) {
const EQS = Components.classes["@mozilla.org/event-queue-service;1"].getService(Components.interfaces.nsIEventQueueService);
th = EQS.getSpecialEventQueue(EQS.CURRENT_THREAD_EVENT_QUEUE);
} else {
th = Components.classes["@mozilla.org/thread-manager;1"].getService().mainThread;
}
dnslistener.parent = this;
dnslistener.host = host;
dns.asyncResolve(host, 0, dnslistener, th);
return ['pending'];
} else {
var ns = dns.resolve(host, true);
var ip = new Array();
while (ns && ns.hasMore()) {
ip.push(ns.getNextAddrAsString());
}
return ip;
}
} catch(e) {
//alert("Resolve exception " + host);
return ['error'];
}
return new Array();
},
// convert num to base 'radix'
dec2radix: function(num, radix, pad) {
var a = [0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'];
var s = '';
while(num > 0) {
s = a[num % radix] + s;
num = Math.floor(num / radix);
}
while((pad - s.length) > 0) {
s = '0' + s;
}
return s;
},
// update the statusbar panel
// @host string hostname to look up
// @ips array ips corresponding to the host (when called from async resolver)
updatestatus: function(host, ips) {
// alert("host: " + host);
if (!host)
return;
var cachekey = 'string_' + host;
var panel = document.getElementById("showip_status_text");
var cacheage = 1*this.prefs.cacheage; // -1: inf, 0: no cache, else time in seconds
var d = new Date();
var now = Math.ceil(d.getTime()/1000);
var cachetime = now;
var text = "";
var status = "";
//var winurl = getBrowser().window.top.currentURI.spec;
var winurl = null;
try {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
winurl = mainWindow.getBrowser().currentURI.host;
} catch(e) {
// firefox 2.0 or no url, http is a guess...
winurl = 'http://' + host;
}
if ((winurl != host) && ((host != 'none') || (winurl))) {
//alert('Ignoring update for ' + host + ', visible url ' + winurl);
return;
}
this.currenthost = host;
if (host == this.displayhost) {
// optimize out about 4/5 of all calls...
return;
}
if( (this.prefs.forcesocks == false) && (this.socks_remote_dns || this.useproxy(winurl))) {
panel.setAttribute("label", host);
panel.label = host;
panel.setAttribute("tooltiptext", this.strings.getFormattedString("socksdisabled", []));
return;
}
// cache handling
if (!ips && this.dnscache[cachekey] && (cacheage != 0)) {
var tmp = this.dnscache[cachekey];
//alert("Tmp " + tmp.join(","));
cachetime = tmp[0];
var expire = 1*cachetime + 1*cacheage;
// alert("Expire " + host + " " + expire + " now " + now + " " + cacheage);
if ((expire > now) || (cacheage == -1)) {
ips = tmp.slice(1);
} else
ips = this.resolveIp(host);
} else if (!ips)
ips = this.resolveIp(host);
// no result yet, async lookup
if (ips.length && (ips[0] == 'pending')) {
text = this.strings.getString("pending");
panel.setAttribute("label", text);
panel.label = text;
this.panelText = text;
return;
}
if (ips.length && (ips[0] == 'error')) {
//text = this.strings.getString("pending");
panel.setAttribute("label", "dns error");
panel.label = text;
this.panelText = "dns error";
return;
}
// cache value
if (ips && !this.dnscache[cachekey] && (cacheage != 0)) {
if (this.dnscache.length > 400)
this.dnscache.shift();
// save current time, and break references!
var x = now + ',' + ips.join(',');
this.dnscache[cachekey] = x.split(',');
}
if (ips.length) {
var j = 0;
text = ips[j];
// if ipv6 is disabled try to find a ipv4 address
// for display
while (!this.ipv6enabled && (text.indexOf(':') != -1) &&
( j < ips.length) ) {
text = ips[j];
j++;
}
// if ipv6 is enabled try to find a ipv6 address
// for display
while (this.ipv6enabled && (text.indexOf('.') != -1) &&
( j < ips.length) ) {
text = ips[j];
j++;
}
} else
text = this.strings.getString("nopage");
// text is ip or host here
if (text.indexOf(":") != -1) {
// ipv6
status = "ipv6";
} else if (text.indexOf(".") != -1) {
// ipv4
status = "ipv4";
// 0: break; // decimal
if (this.prefs.ipv4style) {
var n = text.split('.');
var i;
for(i=0;i<4;i++) {
n[i]=parseInt(n[i]);
}
switch(this.prefs.ipv4style) {
case 1:
for(i=0;i<4;i++) {
n[i] = this.dec2radix(n[i], 8, 4);
}
text = n.join('.');
break; // octal
case 2:
for(i=0;i<4;i++) {
n[i] = '0x' + this.dec2radix(n[i], 16, 2);
}
text = n.join('.');
break; // hex
case 3:
text = (n[0]*16777216)+(n[1]*65536)+(n[2]*256)+n[3];
break; // dword
}
}
} else {
// unknown
status = "unknown";
}
this.currentip = ips.join(',');
if (ips.length > 1)
text += ' +' + (ips.length - 1);
// text += ' @' + cachetime;
this.currentstatus = status;
panel.setAttribute("label", text);
panel.label = text;
panel.setAttribute("tooltiptext", this.strings.getFormattedString("localips", [this.getLocalIp()]));
panel.setAttribute("style", "color:" + this.prefs.color[status]+";");
this.panelText = text;
/*
var popup = document.getElementById("showip_ipmenu");
if (popup) {
// re-arm
popup.onpopupshowing = function() {showipExt.AddIPItems(this);};
}
*/
this.displayhost = host;
return;
},
showPopup: function(e,o) {
var popup = document.getElementById("showip_popup");
//alert('click ' + e.button + ' panelText ' + this.panelText);
switch(e.button) {
case 0: //left
this._AddPopupItems("showip_popup","H",this.currenthost, 1);
break;
case 1: //middle?
this.openurl('http://dnstools.l4x.org/##',this.currenthost);
return;
break;
case 2: //right
if (this.socks_remote_dns) {
this._AddPopupItems("showip_popup","H",this.currenthost, 1);
break;
}
var ip = this.currentip;
var ips = ip.split(',');
if (ips.length == 1) {
if (ip.indexOf(":") == -1) {
this._AddPopupItems("showip_popup","4",ip,1);
} else {
this._AddPopupItems("showip_popup","6",ip,1);
}
break;
}
// deletes all items
this._AddPopupItems("showip_popup","M","Multiple...",1);
// TODO sort by real IP value
ips.sort();
// show one submenus for every IP
var i;
for(i = 0; i < ips.length; i++) {
var xip = ips[i];
var menu = document.createElement("menu");
menu.setAttribute("label", xip);
popup.appendChild(menu);
var mp = document.createElement("menupopup");
mp.id = "showip_ipmenu_" + xip;
// dummy function to prevent recursion
mp.onpopupshowing = function() {};
menu.appendChild(mp);
if (xip.indexOf(":") == -1) {
this._AddPopupItems("showip_ipmenu_" + xip, "4", xip, 0);
} else {
this._AddPopupItems("showip_ipmenu_" + xip, "6", xip, 0);
}
}
break;
}
popup.showPopup(e.target,-1,-1,"popup","bottomleft","topleft");
},
// build popup menu
// @ident 4, 6 or H
// @hostname IP or Hostname
_AddPopupItems: function(popupname, ident, hostname, header) {
var popup = document.getElementById(popupname);
var item;
if (!popup) {
return;
}
// top 3 items remain (currentip, seperator, copy to clipboard
if (popup.childNodes.length > 1)
for(var j=popup.childNodes.length - 1; j>=0; j--)
popup.removeChild(popup.childNodes.item(j));
if (header) {
item = document.createElement("menuitem");
if (ident == 'H') {
item.setAttribute("label", this.strings.getFormattedString("hostmenutitle" , [hostname]));
} else {
item.setAttribute("label", this.strings.getFormattedString("ipmenutitle" , [hostname]));
}
popup.appendChild(item);
item = document.createElement("menuseparator");
popup.appendChild(item);
}
item = document.createElement("menuitem");
item.setAttribute("label", this.strings.getFormattedString("copytoclipboard",[]));
if (ident == 'M') {
item.setAttribute("oncommand", 'showipExt.copytoclip("'+this.currentip+'");');
} else {
item.setAttribute("oncommand", 'showipExt.copytoclip("'+hostname+'");');
}
popup.appendChild(item);
var entries = this.prefs.menuurls.split("||");
for(var i = 0; i < entries.length; i++) {
var parts = entries[i].split("|");
if (parts.length != 3)
continue;
if (parts[0].indexOf(ident) == -1 )
continue;
item = document.createElement("menuitem");
item.setAttribute("label", parts[1]);
item.setAttribute("oncommand", "showipExt.openurl(\"" + parts[2] + "\",\"" + hostname + "\",\"" + ident + "\")");
popup.appendChild(item);
}
/*
item = document.createElement("menuitem");
item.setAttribute("label", "socketping");
item.setAttribute("oncommand", "showipExt.socketping(\"" + hostname + "\")");
popup.appendChild(item);
*/
},
// openurl in newtab/hiddentab/same tab
openurl: function(url, rep, ident) {
// complete uri
url = url.replace(/###/, encodeURIComponent(getBrowser().currentURI.spec));
url = url.replace(/#U#/, encodeURIComponent(getBrowser().currentURI.spec));
// only domain/ip
url = url.replace(/##/, rep);
if (this.currentip) {
url = url.replace(/#I#/, this.currentip);
}
// extract domain name
if (this.currenthost) {
var dn = this.currenthost;
var x = dn.split(/\./);
if (x.length > 1) {
var tld = x[x.length - 1];
var sld = x[x.length - 2];
dn = sld + '.' + tld;
// handle co.uk etc.
if ((sld.length < 3) && (x.length > 2))
dn = x[x.length - 3] + '.' + dn;
}
url = url.replace(/#D#/, dn);
}
if (url.indexOf('!') == 0) {
// call local program
// create an nsILocalFile for the executable
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(url.substr(1));
// create an nsIProcess
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(file);
// Run the process.
// If first param is true, calling process will be blocked until
// called process terminates.
// Second and third params are used to pass command-line arguments
// to the process.
var args = [rep,encodeURIComponent(getBrowser().currentURI.spec)];
process.run(false, args, args.length);
return;
}
if (this.prefs.newtab) {
var tab = getBrowser().addTab(url);
if (!this.prefs.hiddentab)
getBrowser().selectedTab = tab;
} else
getBrowser().loadURI(url);
},
// copy first argument to clipboard
copytoclip: function(host) {
const gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
.getService(Components.interfaces.nsIClipboardHelper);
gClipboardHelper.copyString(host);
},
socketping: function(host) {
var transportService =
Components.classes["@mozilla.org/network/socket-transport-service;1"]
.getService(Components.interfaces.nsISocketTransportService);
var socket = transportService.createTransport(null,0,host,80, null);
this.TPEventSink = {
onTransportStatus: function( aTransport,aStatus,aProgress,aProgressMax) {
alert("TP" + aStatus + " " + aProgress);
},
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsITransportEventSink))
return this;
throw Components.results.NS_NOINTERFACE;
}
}
//socket.setEventSink(this.TPEventSink,null);
var ostream = socket.openOutputStream(0,0,0);
ostream.write("1",1);
ostream.close()
//alert(socket.getPeerAddr());
},
httplistenerInit: function() {
this.HttpObserver = {
observe : function(aSubject, aTopic, aData) {
// Make sure it is our connection first.
if (aSubject == gChannel) {
var httpChannel = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
if (aTopic == "http-on-modify-request") {
// ...
} else if (aTopic == "http-on-examine-response") {
// ...
}
}
},
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIObserver))
return this;
throw Components.results.NS_NOINTERFACE;
}
};
// get the observer service and register for the two coookie topics.
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(listener, "http-on-modify-request", false);
observerService.addObserver(listener, "http-on-examine-response", false);
},
dummy: function() {
} // without a comma
}; // showipExt